package run.graphics;

import static run.scenario.ScenarGenerator.ValeursImages;
import static run.scenario.ScenarGenerator.ValeursSides;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import run.ScenarioManager;

public class ExpeScreen extends JFrame {
	
	public class AnswerButton extends JButton {
		
		private static final long serialVersionUID = 5884182415205269571L;
		
		private String answer;
		
		public AnswerButton(String answer, Image image) {
			super(new ImageIcon(image.getScaledInstance((int)(image.getWidth(null)/3), (int)(image.getHeight(null)/3), 
					Image.SCALE_SMOOTH)));
			this.answer = answer;
		}
		
		public AnswerButton(String answer, String label) {
			super(label);
			this.answer = answer;
		}
		
		public String getAnswer() {
			return answer;
		}
	}
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 483010873546821628L;
	
	public static final int CROSS_SIZE = 30;
	
	public static final int BUTTON_BAR_WIDTH = 700;
	public static final int BUTTON_BAR_GAP = 20;
	
	public static final String IMAGES_FOLDER = "img";
	public static final String EXTENSION = ".png";
	public static final String LINES_PATH = "img" + File.separator + "Lines" + EXTENSION;
	
	///////////////////////////////////////////////////////////////////////////
	
	private ScenarioManager manager;
	
	private Image[] images;
	private Image[] sides;
	private Image lines;
	private int leftIndex, rightIndex;
	private int sideIndex;
	
	private Rectangle[] buttonBorders;
	private AnswerButton[] buttons;
	private String selection = "";
	
	private int imageSize; // images should be square
	private int arrowSize;
	private int imageDistance;
	private boolean vertical, circle;
	
	private Robot robot;
	
	public ExpeScreen(final ScenarioManager manager, int imageSize, int arrowSize, 
			int imageDistance, boolean vertical, boolean circle, boolean dunno) {
		
		super();
		
		try {
			robot = new Robot();
		} catch (AWTException e1) {
			e1.printStackTrace();
			System.exit(-1);
		}
		
		this.manager = manager;
		this.imageSize = imageSize;
		this.arrowSize = arrowSize;
		this.imageDistance = imageDistance;
		this.vertical = vertical;
		this.circle = circle;
		
		JComponent glassPane = ((JComponent) getGlassPane());
		
		glassPane.setLayout(new BorderLayout());
		
//		JPanel labelPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
//		labelPanel.setPreferredSize(new Dimension(500, 200));
//		JLabel answerLabel = new JLabel(""); // Answer! Now!
//		labelPanel.add(answerLabel);
//		glassPane.add(labelPanel, BorderLayout.NORTH);
		
		JPanel buttonsPanel = new JPanel();
		
		if (vertical) {
			buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS));
		} else if (circle){
			// buttonsPanel.setLayout(new GridBagLayout());
		} else {
			buttonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		}
		
		glassPane.add(buttonsPanel, BorderLayout.CENTER);
		
		JPanel okPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
		glassPane.add(okPanel, BorderLayout.SOUTH);
		
		try{
			
			images = new Image[ValeursImages.length];
			for (int i = 0 ; i < ValeursImages.length ; i++) {
				images[i] = ImageIO.read(new File(IMAGES_FOLDER + File.separator + ValeursImages[i] + EXTENSION));
			}
			
			sides = new Image[ValeursSides.length];
			for (int i = 0 ; i < ValeursSides.length ; i++) {
				sides[i] = ImageIO.read(new File(IMAGES_FOLDER + File.separator + ValeursSides[i] + EXTENSION));
			}
			
			lines = ImageIO.read(new File(LINES_PATH));
			
			buttons = new AnswerButton[images.length];
			for (int i = 0 ; i < images.length ; i++) {
				
				// buttons[i] = new AnswerButton(ValeursImages[i], images[i]);
				buttons[i] = new AnswerButton(ValeursImages[i], manager.getWord(ValeursImages[i]));
				buttons[i].addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						selection = ((AnswerButton) e.getSource()).getAnswer();
//						selection = selection.substring(0, selection.length()-4);
						manager.incrementNbAnswers();
					}
				});
				buttons[i].setAlignmentX(Component.CENTER_ALIGNMENT);
				buttonsPanel.add(buttons[i]);
			}
//			buttonsPanel.setBackground(Color.red);
			
			JButton okButton = new JButton("OK");
			okButton.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent arg0) {
					manager.validate(selection);
				}
			});
			okPanel.add(okButton);
			
			if (dunno) {
				JButton dnButton = new JButton(manager.getWord("Dunno"));
				dnButton.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent arg0) {
						manager.dunno();
					}
				});
				okPanel.add(dnButton);
			}
			
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(-1);
		}
		
		addKeyListener(new KeyAdapter() {
			@Override
			public void keyTyped(KeyEvent e) {
				super.keyTyped(e);
				manager.startTrials();
			}
		});
		
		setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
//		setResizable(true);
		
	    GraphicsDevice gd =
	            GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();

	    if (gd.isFullScreenSupported()) {
	        setUndecorated(true);
	        gd.setFullScreenWindow(this);
	    } else {
	        System.err.println("Full screen not supported");
	        setSize(100, 100); // just something to let you see the window
	        setVisible(true);
	    }
		
		setBackground(Color.white);
		
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		pack();
		
	}
	
	public void drawCross(Graphics2D g2d) {
		// Fixation cross
		g2d.setPaint(Color.black);
		g2d.drawLine(getWidth() / 2 - CROSS_SIZE / 2, 
				getHeight() / 2,
				getWidth() / 2 + CROSS_SIZE / 2,
				getHeight() / 2);
		g2d.drawLine(getWidth() / 2, 
				getHeight() / 2 - CROSS_SIZE / 2,
				getWidth() / 2,
				getHeight() / 2 + CROSS_SIZE / 2);
	}
	
	@Override
	public void paint(Graphics g) {
		
		super.paint(g);
		Graphics2D g2d = (Graphics2D) g;
		Image currentImage;
		
		switch (manager.getCurrentState()) {

		case BLANK:
			drawCross(g2d);
			return;

		case IMAGES:

			drawCross(g2d);
			
			currentImage = images[leftIndex];

			g2d.drawImage(currentImage, 
					getWidth() / 2 - arrowSize / 2 - imageDistance - imageSize, 
					getHeight() / 2 - imageSize / 2, 
					getWidth() / 2 - arrowSize / 2 - imageDistance,
					getHeight() / 2 + imageSize / 2,
					0, 0, currentImage.getWidth(null), currentImage.getHeight(null),
					null);

			currentImage = images[rightIndex];

			g2d.drawImage(currentImage, 
					getWidth() / 2 + arrowSize / 2 + imageDistance,
					getHeight() / 2 - imageSize / 2, 
					getWidth() / 2 + arrowSize / 2 + imageDistance + imageSize,
					getHeight() / 2 + imageSize / 2,
					0, 0, currentImage.getWidth(null), currentImage.getHeight(null),
					null);

			currentImage = sides[sideIndex];

			g2d.drawImage(currentImage, 
					getWidth() / 2 - arrowSize / 2, 
					getHeight() / 2 - arrowSize / 2, 
					getWidth() / 2 + arrowSize / 2,
					getHeight() / 2 + arrowSize / 2,
					0, 0, currentImage.getWidth(null), currentImage.getHeight(null),
					null);
			break;

		case ANSWER:

			if (circle) {
				
				double a = - Math.PI/2;
				double d = 200;
				
				for (AnswerButton b : buttons) {
					
					b.setLocation(
							(int)(getWidth()/2+d*Math.cos(a) - b.getWidth()/2), 
							(int)(getHeight()/2+d*Math.sin(a) - b.getHeight()/2)
					);
					
					a += 2 * Math.PI / 5;
					
				}
				
			}
			break;
			
		default:
			System.err.println("Unknown trial state...");
			break;
		}
		
	}
	
	public void updateTrialData(int leftIndex, int rightIndex, int sideIndex) {
		this.leftIndex = leftIndex;
		this.rightIndex = rightIndex;
		this.sideIndex = sideIndex;
	}
	
	public void emptyScreen() {
		
		getGlassPane().setVisible(false);
		
		repaint();
	}
	
	public void displayTrial() {
		repaint();
	}
	
	public void displayLines() {
		repaint();
	}
	
	public void displayButtons() {
		
		getGlassPane().setVisible(true);
		robot.mouseMove(getWidth()/2, getHeight()/2);
		
		repaint();
	}
	
}
